<?php

namespace app\admin\controller;

use Exception;
use johnxu\tool\exception\InvalidParamException;
use johnxu\tool\exception\InvalidSignatureException;
use johnxu\tool\exception\InvalidVerifyException;
use johnxu\tool\Jwt;
use johnxu\tool\Restful;
use johnxu\tool\Str;
use think\Collection;
use think\Container;
use think\Model;
use think\Request;
use think\Validate;

class Base extends Restful
{

    /**
     * @var Model
     */
    protected $model;

    /**
     * @var Validate
     */
    protected $validate;

    /**
     * @var Request
     */
    protected $request;

    /**
     * @var null|object 用户信息
     */
    protected $user;

    /**
     * @var Jwt
     */
    protected $jwt;

    protected $page;
    protected $pageSize;

    public function __construct()
    {
        $this->_initialize();
    }

    protected function _initialize()
    {
        $this->request = Container::getInstance()->request;
        $this->jwt     = new Jwt();
        $this->jwt->setKey(config('johnxu.jwt_key'));
        $this->parseUserinfo();
        $this->page     = $this->request->get('page', config('johnxu.default_page'));
        $this->pageSize = $this->request->get('page_size', config('johnxu.default_page_size'));
    }

    /**
     * 创建权限认证token
     * @param array $payload
     * @return string
     * @throws Exception
     */
    protected function createJwtToken(array $payload = [])
    {
        $this->jwt->setIss('johnxu');
        $this->jwt->setIat(time());
        $this->jwt->setSub('jwt authorization');
        $this->jwt->setJti(Str::getInstance()->getMachineCode(3, 8, ''));
        $this->jwt->setNbf(time());
        $this->jwt->setExp(time() + config('johnxu.expire_time'));
        $this->jwt->setAud($this->request->domain());
        $this->jwt->setPayload($payload);
        try {
            return $this->jwt->getToken();
        } catch (InvalidParamException $e) {
            $this->fail(200, -1, $e->getMessage());
        }
    }

    /**
     * 列表
     */
    public function index()
    {
        if (!$this->model) {
            $this->model = model($this->request->controller());
        }

        $list  = $this->model->page($this->page, $this->pageSize)->select();
        $list  = Collection::make($list)->toArray();
        $total = $this->model->count('*');

        $this->afterIndex($list);

        $this->ok(200, [
            'list'  => $list,
            'total' => $total,
        ]);
    }

    protected function afterIndex(&$params)
    {

    }

    /**
     * 添加操作
     */
    public function add()
    {
        $params = $this->request->post();
        if ($this->validate) {
            if (!$this->validate->scene('add')->check($params)) {
                $this->fail(200, 1, (string )$this->validate->getError());
            }
        }

        if (!$this->model) {
            $this->model = model($this->request->controller());
        }

        $insertId = $this->model->strict(false)->insertGetId($params);

        if ($insertId) {
            $params['id'] = $insertId;
            $this->afterAdd($params);
            $this->ok(200, $params);
        } else {
            $this->fail(200, 1, '添加失败');
        }
    }

    /**
     * 添加完成后置操作
     * @param array $params
     */
    protected function afterAdd(array &$params)
    {
    }

    /**
     * 编辑
     * @param int $id
     */
    public function edit(int $id = 0)
    {
        if (!$this->model) {
            $this->model = model($this->request->controller());
        }
        $row = $this->model::get($id);
        if (!$row) {
            $this->fail(200, 1, '该数据不存在');
        }

        $params = $this->request->post();
        $flag   = $row->data($params)->save();
        if ($flag !== false) {
            $this->ok(200, $row->getData());
        } else {
            $this->fail(200, 1, '修改失败');
        }
    }

    /**
     * 删除
     * @param int $id
     */
    public function del(int $id = 0)
    {
        if (!$this->model) {
            $this->model = model($this->request->controller());
        }
        $row = $this->model::get($id);
        if (!$row) {
            $this->fail(200, 1, '该数据不存在');
        } else {
            if ($row->delete()) {
                $this->ok(200, $row);
            } else {
                $this->fail(200, 1, '删除失败');
            }
        }
    }

    /**
     * 解析authorization里面的用户信息
     */
    protected function parseUserinfo()
    {
        $authorization = $this->request->header('Authorization');
        if ($authorization) {
            try {
                $payload = $this->jwt->verify($authorization);
                if ($payload) {
                    $this->user = (object)$payload['payload'];
                }
            } catch (InvalidSignatureException $e) {
                $this->fail(200, -1, $e->getMessage());
            } catch (InvalidVerifyException $e) {
                $this->fail(200, -1, $e->getMessage());
            }
        }
    }
}